﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ChessOnline
{
    public enum LiteralCoord
    {
        a = 0,
        b = 1,
        c = 2,
        d = 3,
        e = 4,
        f = 5,
        g = 6,
        h = 7
    };

    public class Coordinate
    {
        private LiteralCoord literal;

        public LiteralCoord Literal
        {
            get { return literal; }
            set { literal = value; }
        }

        private int number;

        public int Number
        {
            get { return number; }
            set { number = value; }
        }

        public void Up()
        {
            Number += (Number >= 8 ?  0 : 1);
        }

        public void Down()
        {
            Number -= (Number <= 1 ? 0 : 1);
        }

        public void Left()
        {
            Literal -= ((int) Literal <= 0 ? 0 : 1);
        }

        public void Right()
        {
            Literal += ((int) Literal >= 7 ? 0 : 1);
        }

        public Coordinate NextUp()
        {
            Coordinate coord = new Coordinate();
            coord.Literal = Literal;
            coord.Number = Number;
            coord.Up();
            return coord;
        }

        public Coordinate NextDown()
        {
            Coordinate coord = new Coordinate();
            coord.Literal = Literal;
            coord.Number = Number;
            coord.Down();
            return coord;
        }

        public Coordinate NextLeft()
        {
            Coordinate coord = new Coordinate();
            coord.Literal = Literal;
            coord.Number = Number;
            coord.Left();
            return coord;
        }

        public Coordinate NextRight()
        {
            Coordinate coord = new Coordinate();
            coord.Literal = Literal;
            coord.Number = Number;
            coord.Right();
            return coord;
        }

        public bool AtTheBottomEdge()
        {
            return (this.Number == 1);
        }

        public bool AtTheTopEdge()
        {
            return (this.Number == 8);
        }

        public bool AtTheLeftEdge()
        {
            return (this.Literal == LiteralCoord.a);
        }

        public bool AtTheRightEdge()
        {
            return (this.Literal == LiteralCoord.h);
        }

        public static bool operator==(Coordinate a, Coordinate b)
        {
            return ((int)a.Literal == (int)b.Literal && a.Number == b.Number);
        }

        public static bool operator !=(Coordinate a, Coordinate b)
        {
            return (!(a == b));
        }

        public static bool operator >(Coordinate a, Coordinate b)
        {
            if ((int)a.Literal > (int)b.Literal)
            {
                return true;
            }
            else if (a.Number > b.Number)
            {
                return true;
            }
            else return false;                
        }

        public static bool operator <(Coordinate a, Coordinate b)
        {
            return (!(a > b) && a != b);
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Coordinate);
        }

        public bool Equals(Coordinate obj)
        {
            return ((int)this.Literal == (int)obj.Literal && this.Number == obj.Number);
        }

        public int GetHashCode(Coordinate obj)
        {
            return obj.Number.GetHashCode()*obj.Literal.GetHashCode();
        }

        public override int GetHashCode()
        {
            return Number.GetHashCode() * Literal.GetHashCode();
        }

        public static Direction FindOutDirection(Coordinate a, Coordinate b)
        {
            if (a.Number == b.Number && a.Literal < b.Literal)
                return Direction.East;
            else if (a.Number == b.Number && a.Literal > b.Literal)
                return Direction.West;
            else if (a.Number > b.Number && a.Literal == b.Literal)
                return Direction.South;
            else if (a.Number < b.Number && a.Literal == b.Literal)
                return Direction.North;
            else if (a.Number > b.Number && a.Literal > b.Literal)
                return Direction.SouthWest;
            else if (a.Number > b.Number && a.Literal < b.Literal)
                return Direction.SouthEast;
            else if (a.Number < b.Number && a.Literal > b.Literal)
                return Direction.NorthWest;
            else if (a.Number < b.Number && a.Literal < b.Literal)
                return Direction.NorthEast;

            return Direction.North;
         }
    }
}
